package ubi.quando.App;

import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.osmdroid.util.GeoPoint;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

public class GeoToAddress {

	// TODO: maybe should change to https
	private static final String SOURCE = "http://maps.googleapis.com/maps/api/geocode/";
	private static final String ADDRESS = "xml?address=";
	private static final String LATLNG = "xml?latlng=";
	private static final String SENSOR = "&sensor=false";

	public static String getAddress(GeoPoint point)
	{
		return "Jerusalem";
//		String pointRequest = SOURCE + LATLNG;
//		String lat = String.valueOf(point.getLatitudeE6());
//		String lng = String.valueOf(point.getLongitudeE6());
//		lat = lat.substring(0, 2) + "." + lat.substring(2);
//		lng = lng.substring(0, 2) + "." + lng.substring(2);
//		
//		pointRequest = pointRequest + lat + "," + lng + SENSOR;
//		
//		InputStream in;
//		try {
//			in = Connect(pointRequest);
//		} catch (IOException e) {
//			return null;
//		}
//		
//		Document doc = GetXMLFromStream(in);
//		doc.getDocumentElement().normalize();
//		
//		NodeList nList = doc.getElementsByTagName("formatted_address");
//		Node nNode = nList.item(0);
//		return nNode.getNodeValue();
	}

	public static GeoPoint getGeo(String address) {
		String addressRequest = SOURCE + ADDRESS;
		String[] result = address.split("\\s+");
		for (String info : result) {
			addressRequest = addressRequest + info + "+";
		}

		int lastPlus = addressRequest.lastIndexOf("+");
		addressRequest = addressRequest.substring(0, lastPlus);

		addressRequest += SENSOR;

		InputStream in;
		try {
			in = Connect(addressRequest);
		} catch (IOException e) {
			return null;
		}

		Document doc = GetXMLFromStream(in);
		doc.getDocumentElement().normalize();

		NodeList nList = doc.getElementsByTagName("location");

		for (int temp = 0; temp < nList.getLength(); temp++) {
			Node nNode = nList.item(temp);
			if (nNode.getNodeType() == Node.ELEMENT_NODE) {

				Element eElement = (Element) nNode;

				double lat = getTagValue("lat", eElement);
				double lng = getTagValue("lng", eElement);
				
				return new GeoPoint(lat, lng);
			}
		}
		
		return null;
	}

	private static Document GetXMLFromStream(InputStream in) {

		DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
		DocumentBuilder db;

		try {
			db = dbf.newDocumentBuilder();
		} catch (ParserConfigurationException e) {
			return null;
		}

		try {
			Document doc = db.parse(in);
			return doc;
		} catch (SAXException e) {
			return null;
		} catch (IOException e) {
			return null;
		}

	}

	private static InputStream Connect(String addressRequest)
			throws IOException {
		InputStream in = null;

		URL url = new URL(addressRequest);
		URLConnection conn = url.openConnection();

		if (!(conn instanceof HttpURLConnection)) {
			throw new IOException("Not an HTTP connection");
		}

		try {
			HttpURLConnection httpCon = (HttpURLConnection) conn;
			httpCon.setInstanceFollowRedirects(true);
			httpCon.setRequestMethod("GET");
			httpCon.connect();

			int response = httpCon.getResponseCode();
			if (response == HttpURLConnection.HTTP_OK) {
				in = httpCon.getInputStream();
			}
		} catch (Exception e) {
			throw new IOException("Error in connecting");
		}

		return in;

	}

	private static double getTagValue(String sTag, Element eElement) {
		NodeList nlList = eElement.getElementsByTagName(sTag).item(0)
				.getChildNodes();
		Node nValue = (Node) nlList.item(0);

		return Double.parseDouble(nValue.getNodeValue());
	}
}
